﻿'20130313
Imports System.Text
Imports System.Net.Sockets
Public Structure TelnetCmd
    Shared IAC_WILL_ECHO As Byte() = {&HFF, &HFB, &H1}
    Shared IAC_WILL_SuppressGoAhead As Byte() = {&HFF, &HFB, &H3}
    Shared IAC_DO_ECHO As Byte() = {&HFF, &HFD, &H1}
    Shared IAC_DO_SuppressGoAhead As Byte() = {&HFF, &HFD, &H3}
End Structure
MustInherit Class seTelnet

    Private tempSocket As Socket
    Private IPStr As String
    Private recvBuffer(256) As Byte
    Private msgStr As String

    Sub New(ByVal ip As String)
        IPStr = ip
        msgStr = IPStr & vbCrLf
    End Sub
    Public Function run() As Boolean
        Dim count As Integer = 0
        Dim IsSuccess As Boolean = False
        While count <= 0

            If Me.telnetConnect(Me.IPStr) Then
                count = 255
                If runCmd() Then
                    IsSuccess = True
                Else

                End If
            Else
                count = count + 1
                msgStr += vbCrLf + "telnetConnect Fail " + count.ToString("D2")
            End If
        End While

        Return IsSuccess
    End Function
    Private Function telnetConnect(ByVal ip As String) As Boolean
        Dim isConnect As Boolean = False
        tempSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
        tempSocket.ReceiveTimeout = My.Settings.CmdTimeout
        Try
            tempSocket.Connect(IPStr, 23)
            Array.Clear(recvBuffer, 0, recvBuffer.Length)
            tempSocket.Receive(recvBuffer, TelnetCmd.IAC_WILL_ECHO.Length, SocketFlags.None)
            If BitConverter.ToString(recvBuffer, 0, TelnetCmd.IAC_WILL_ECHO.Length) <> BitConverter.ToString(TelnetCmd.IAC_WILL_ECHO) Then
                '  Me.formMain.BeginInvoke(rebootDelegateObj, _
                '                         New Object() {rowIndex, result, "#TelnetCmd.IAC_WILL_ECHO Fail!"})

                tempSocket.Close()
                Throw New Exception("#TelnetCmd.IAC_WILL_ECHO Fail!")
            End If
            tempSocket.Send(TelnetCmd.IAC_DO_ECHO, 3, SocketFlags.None)
            Array.Clear(recvBuffer, 0, recvBuffer.Length)
            tempSocket.Receive(recvBuffer, TelnetCmd.IAC_WILL_SuppressGoAhead.Length, SocketFlags.None)
            If BitConverter.ToString(recvBuffer, 0, TelnetCmd.IAC_WILL_SuppressGoAhead.Length) <> _
                BitConverter.ToString(TelnetCmd.IAC_WILL_SuppressGoAhead) Then
                tempSocket.Close()
                Throw New Exception("#TelnetCmd.IAC_WILL_SuppressGoAhead Fail!")

            End If
            tempSocket.Send(TelnetCmd.IAC_DO_SuppressGoAhead, 3, SocketFlags.None)
            isConnect = True
        Catch ex As Exception
            ' Me.formMain.BeginInvoke(rebootDelegateObj, New Object() {rowIndex, result, ex.Message})
            Console.WriteLine(ex.ToString)
            tempSocket.Close()
        End Try
        Return isConnect
    End Function
    MustOverride Function runStep(ByVal loginStep As Integer, ByVal sectionStr As String) As RunStepMsg

    Private Function runCmd() As Boolean

        Dim recvLen As Integer
        Dim recvStr As String = ""
        Dim sectionStr As String = ""
        Dim loginStep As Integer = 0
        Dim isSuccess As Boolean = False
        Dim WaitMaxCountWait As Integer = 10
        Dim waitCount As Integer = 0
        Try
            recvLen = tempSocket.Receive(recvBuffer, recvBuffer.Length, SocketFlags.None)
            While recvLen > 0
                recvStr = Encoding.Default.GetString(recvBuffer, 0, recvLen)
                msgStr += recvStr
                sectionStr += recvStr
                '步驟
                Try
                    Select Case Me.runStep(loginStep, sectionStr)
                        Case RunStepMsg.nextStep
                            loginStep = loginStep + 1
                            sectionStr = ""
                        Case RunStepMsg.RunEnd
                            isSuccess = True
                            Exit While
                        Case RunStepMsg.wait
                            waitCount = waitCount + 1
                            If waitCount = WaitMaxCountWait Then
                                Throw New Exception("wait time " + waitCount.ToString)
                            End If
                        Case RunStepMsg.Fail
                            Throw New Exception("telnet Error")
                        Case Else

                    End Select


                Catch ex As Exception
                    Throw ex
                End Try

                recvLen = tempSocket.Receive(recvBuffer, recvBuffer.Length, SocketFlags.None)

            End While

            msgStr += vbCrLf & "#Login Step = " & loginStep & _
                        vbCrLf & "#Connection Break!"
            Console.WriteLine(msgStr)
        Catch ex As Exception
            msgStr += vbCrLf & "#Login Step = " & loginStep & _
                        vbCrLf & ex.Message
            Console.WriteLine(msgStr)
            isSuccess = False
        Finally
            tempSocket.Close()
        End Try

        ' BeginInvoke causes asynchronous execution to begin at the address
        ' specified by the delegate. Simply put, it transfers execution of 
        ' this method back to the main thread. Any parameters required by 
        ' the method contained at the delegate are wrapped in an object and 
        ' passed. 
        ' Me.formMain.BeginInvoke(rebootDelegateObj, New Object() {rowIndex, result, msgStr})
        Return isSuccess
    End Function
    'Telnet輸入
    Protected Sub SocketSend(ByVal Text As String)
        tempSocket.Send(Encoding.Default.GetBytes(Text))
    End Sub

    Public Function getTelnetMsg() As String
        Return msgStr
    End Function

    'Private Function runStep(ByVal loginStep As Integer, ByVal sectionStr As String) As RunStepMsg
    '    Dim isRunEnd As Boolean
    '    Select Case loginStep
    '        Case 0
    '            If (sectionStr.EndsWith("login: ")) Then
    '                tempSocket.Send(Encoding.Default.GetBytes(telnetName & vbCrLf))

    '                Return RunStepMsg.nextStep
    '            End If
    '        Case 1
    '            If (sectionStr.EndsWith("Password: ")) Then
    '                tempSocket.Send(Encoding.Default.GetBytes(telnetPassword & vbCrLf))

    '                Return RunStepMsg.nextStep
    '            End If
    '        Case 2
    '            If (sectionStr.EndsWith("\> ")) Then

    '                tempSocket.Send(Encoding.Default.GetBytes("reboot" & vbCrLf))
    '                Return RunStepMsg.RunEnd
    '            End If
    '        Case Else

    '    End Select
    '    Return RunStepMsg.wait

    'End Function


End Class
 
Enum RunStepMsg
    wait = 0
    nextStep = 1
    RunEnd = 2
    Fail = 254
    null = 255
End Enum

